package com.xt.nettydemo01.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
public class NettyWebSocketServer {

    //项目启动后就需要单独开一个线程 来监听端口的请求
    @PostConstruct
    public void start() {
        new Thread(() ->{
            //boss线程(只需要一个线程来管理)
            NioEventLoopGroup boos = new NioEventLoopGroup(1);
            //worker线程
            NioEventLoopGroup worker = new NioEventLoopGroup();
            try {
                ServerBootstrap bootstrap = new ServerBootstrap().group(boos, worker)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new ChannelInitializer<SocketChannel>() {  //连接处理器
                            /**
                             * 链接到这里后需要初始化
                             * @param socketChannel 连接
                             * @throws Exception 可能出现的异常
                             */
                            @Override
                            protected void initChannel(SocketChannel socketChannel) throws Exception {
                                ChannelPipeline pipeline = socketChannel.pipeline();
                                pipeline.addLast(new HttpServerCodec())
                                        .addLast(new HttpObjectAggregator(65536))
                                        .addLast(new WebSocketServerProtocolHandler("/ws"))
                                        .addLast(new WebSocketMessageHandler());
                            }
                        });
                ChannelFuture future = bootstrap.bind(8081).sync();
                future.channel().closeFuture().sync();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                boos.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }).start();
    }
}
